import matplotlib.pyplot as plt
import math


class Reciprocate_route():
    def __init__(self, length_field=int(), width_field=int(), harvest_width=float(), turn_radius=float()):
        self.length_field = length_field
        self.width_field = width_field
        self.harvest_width = harvest_width
        self.turn_radius = turn_radius
        self.data = [[(0, 0), (0, self.width_field), (self.length_field, self.width_field), (self.length_field, 0)]]

# 确定分行数,以短边为界进行分行  得到的数值是中间的分行数
    def num_line_compute(self):
        if self.length_field > self.width_field:
            if self.width_field % self.harvest_width != 0:
                num_line = math.floor(self.width_field / self.harvest_width)
            else:
                num_line = int(self.width_field / self.harvest_width) - 1
        else:
            if self.length_field % self.harvest_width != 0:
                num_line = math.floor(self.length_field / self.harvest_width)
            else:
                num_line = int(self.length_field / self.harvest_width) - 1
        return num_line

# 提取田块边界坐标
    def boundary_point(self, data=None):
        x_data = []
        for i in range(len(data)):
            x_data.append(data[i][0])
        y_data = []
        for i in range(len(data)):
            y_data.append(data[i][1])
        return x_data, y_data

# 画出田块边界
    def boundary(self):
        plt.rcParams['font.sans-serif'] = ['SimHei']
        plt.rcParams['axes.unicode_minus'] = False
        global x_one
        global y_one
        x_one = []
        y_one = []
        for i in range(len(self.data)):
            x_one, y_one = self.boundary_point(data=self.data[i])
        x_one.append(x_one[0])
        y_one.append(y_one[0])
        return x_one, y_one

# 得到偏置后的坐标点集合  往复式分长短边坐标
    def line_bias_list(self):
        global x_bias
        global y_bias
        x_bias = []
        y_bias = []
        if self.length_field < self.width_field:
            for i in range(1, self.num_line_compute()+1):
                x_bias_one = x_one[0] + i * self.harvest_width
                x_bias_two = x_bias_one
                y_bias_one = y_one[0] + self.harvest_width
                y_bias_two = self.width_field - self.harvest_width
                x_bias.append(x_bias_one)
                x_bias.append(x_bias_two)
                y_bias.append(y_bias_one)
                y_bias.append(y_bias_two)
        else:
            for i in range(1, self.num_line_compute()+1):
                x_bias_one = x_one[0] + self.harvest_width
                x_bias_two = self.length_field - self.harvest_width
                y_bias_one = i * self.harvest_width
                y_bias_two = y_bias_one
                x_bias.append(x_bias_one)
                x_bias.append(x_bias_two)
                y_bias.append(y_bias_one)
                y_bias.append(y_bias_two)
        self.divide_axis(x_one_group=x_bias, y_one_group=y_bias)
        print(self.divide_x_one)
        print(self.divide_y_one)
        # return x_bias, y_bias

# 坐标列表分割
    def divide_axis(self, x_one_group=None, y_one_group=None):
        x_one_groups = zip(*(iter(x_one_group),) * 2)
        y_one_groups = zip(*(iter(y_one_group),) * 2)
        self.divide_x_one = [list(i) for i in x_one_groups]
        self.divide_y_one = [list(i) for i in y_one_groups]
        count = len(y_one_group) % 2
        self.divide_x_one.append(x_one_group[-count:]) if count != 0 else self.divide_x_one
        self.divide_y_one.append(y_one_group[-count:]) if count != 0 else self.divide_y_one

# 画出偏置后的矩形框图
    def bias_route_visual(self):
        plt.plot(x_one, y_one, c='k')
        for i in range(0, len(self.divide_x_one)):
            plt.plot(self.divide_x_one[i], self.divide_y_one[i], c='r')
        plt.title('完成收获所需要的转弯次数为：' + str(self.num_radius()) + '次' + '——' + '路径长度为：' + str((self.num_line_compute() * self.length_field) + self.length_radius()))
        # plt.axis('off')
        plt.show()

# 计算整田块回转路径的转弯次数并显示
    def num_radius(self):
        num_radius = self.num_line_compute()
        return num_radius

# 计算整田块回转路径的转弯路径总长度
    def length_radius(self):
        L = (2 * self.turn_radius) * (math.pi - 2 * (math.atan(self.harvest_width / ((4 * self.turn_radius ** 2 - self.harvest_width ** 2) ** 0.5))))
        length_radius = L * self.num_radius()
        return length_radius

# 计算该收获方式下的行驶路径总长
    def all_length(self):
        radius_length = self.length_radius()
        if self.length_field > self.width_field:
            straight_length = (self.num_line_compute() + 1) * self.length_field
        else:
            straight_length = (self.num_line_compute() + 1) * self.width_field
        all_length = radius_length + straight_length
        return all_length


field_boundary = Reciprocate_route(71, 34, 3, 6)
field_boundary.boundary()
field_boundary.line_bias_list()
field_boundary.bias_route_visual()
print('该收获方式下的总路径长度为：' + str(field_boundary.all_length()))
